/*
 * ScriptStructure.h
 * VB Script Analyzer
 * @author Gregoire JACOB (gregoire.jacob@orange-ftgroup.com)
 * @date 27/08/2008
 * @version 1.1
 */

#define NAME_MAX_LENGTH  256
#define LINE_LENGTH		 502
#define ARG_MAX_NB		 15
#define FSO_NAME		 "Scripting.FileSystemObject"
#define SHELL_NAME		 "WScript.Shell"
#define NET_NAME		 "WScript.Network"
#define MAIL_NAME		 "Outlook.Application"
#define OBJECT_CREATION	 "CreateObject"
#define OBJECT_CREATION2 "ActiveXObject"
//Line types
#define COMMENT			1
#define MARKUP			2
#define DECLARATION		3
#define MANAGER			4
#define LOCALCALL		5
#define SYSCALL			6
#define AFFECTATION		7

#define MAXNBMANAGER 40
//Managers structure
struct MANAG_ENTRY{
	int		nbfsoalias;
	int		nbfsoobj;
	char *	FileSystemAliases[MAXNBMANAGER];
	char *	FileSystemObjects[MAXNBMANAGER];
	int		nbshellalias;
	int		nbshellobj;
	char *	ShellAliases[MAXNBMANAGER];
	char *	ShellObjects[MAXNBMANAGER];
	int		nbnetalias;
	int		nbnetobj;
	char *	NetworkAliases[MAXNBMANAGER];
	char *	NetworkObjects[MAXNBMANAGER];
	int		nbmailalias;
	int		nbmailobj;
	char *	MailAliases[MAXNBMANAGER];
	char *	MailObjects[MAXNBMANAGER];
	int		nbunknownobj;
	char *	UnknownManagers[MAXNBMANAGER];
};

//Line structure
struct LINE{
	int		type;
	char	line[LINE_LENGTH];
};

//Function structure
struct FUNC_ENTRY{
	char	name[NAME_MAX_LENGTH];
	int		nbarg;
	char *	arguments[ARG_MAX_NB];
	int		nbvar;
	char *	variables[50];
	struct	MANAG_ENTRY managers;
	unsigned long begin;	//offsets in the script file
    unsigned long codepos; 
	unsigned long end; 
	int beingexecuted;
	int		nblines;
	struct LINE * code;
};

//Procedure structure
struct PROC_ENTRY{
	char	name[NAME_MAX_LENGTH];
	int		nbarg;
	char *	arguments[ARG_MAX_NB];
	int		nbvar;
	char *	variables[50];
	struct	MANAG_ENTRY managers;
	unsigned long begin;	//offsets in the script file
	unsigned long codepos; 
    unsigned long end;
	int beingexecuted;
	int		nblines;
	struct LINE * code;
};

//Global structures of a script
struct SCRIPT{
	char	name[NAME_MAX_LENGTH];
	int		nbvar;
	char *	variables[100];
	struct	MANAG_ENTRY managers;
	int		nbfunc;
	struct	FUNC_ENTRY functionslist[30];
	int		nbproc;
	struct	PROC_ENTRY procedureslist[30];
	int		strciphered;			//1 if ciphered else 0
	int		cipherfunction;			//index in functionlist
	char	cipherscript[NAME_MAX_LENGTH];
	int		nblines;
	struct LINE * code;
};

/**
 * addManagerAlias()
 * addManagerObject()
 * @param the manager structure to update
 * @param the type of manager (TFSO,TSHELL,TNETW)
 * @param the manager alias or object
 * @warning aliases and objects must be null-terminated
 */
#define TFSO	1
#define TSHELL  2
#define	TNETW	3
#define	TMAIL	4
void addManagerAlias(struct MANAG_ENTRY * managers, int type, char * alias);
void addManagerObject(struct MANAG_ENTRY * managers, int type, char * object);

/**
 * printStructures()
 * @param the structure to render
 * Print the different information of a given structure in the console
 */
void printManagers(struct MANAG_ENTRY * managers);
void printLine(struct LINE * line);
void printFunction(struct FUNC_ENTRY * function);
void printProcedure(struct PROC_ENTRY * procedure);
void printScript(struct SCRIPT * script);
void printfManagers(FILE * f, struct MANAG_ENTRY * managers);
void printfLine(FILE * f, struct LINE * line);
void printfFunction(FILE * f, struct FUNC_ENTRY * function);
void printfProcedure(FILE * f, struct PROC_ENTRY * procedure);
void printfScript(FILE * f, struct SCRIPT * script);

/**
 * insideFunction()
 * insideProcedure()
 * @param the current script structure
 * @param the current position in the script file
 * @return 1 if the position is inside a function or a procedure, otherwise 0
 * Test if the given position refers respectively to a function or a procedure
 */
int insideFunction(struct SCRIPT * script, int position);
int insideProcedure(struct SCRIPT * script, int position);
/**
 * recoverMaximalPosition()
 * @param the current script structure
 * @param the location (main/function/procedure)
 * @return the maximal position until which we remain inside the location
 */
int recoverMaximalPosition(struct SCRIPT * script, unsigned long location);

/**
 * isFileManager()
 * isShellManager()
 * isNetworkManager()
 * isMailManager()
 * @param the current manager structure
 * @param the current token
 * @return 1 if the token is a manager, otherwise -1
 * Test if the given token is in the manager table as object
 */
int isFileManager(struct MANAG_ENTRY * managers, char *  token);
int isShellManager(struct MANAG_ENTRY * managers, char *  token);
int isNetworkManager(struct MANAG_ENTRY * managers, char *  token);
int isMailManager(struct MANAG_ENTRY * managers, char *  token);
int isUnknownManager(struct MANAG_ENTRY * managers, char *  token);

/**
 * isLocalFunction()
 * isLocalProcedure()
 * @param the current script structure
 * @param the current token
 * @return the function index if the token is a function or a procedure, otherwise -1
 * Test if the given token is in the manager table as object
 */
int isLocalFunction(struct SCRIPT * script, char *  token);
int isLocalProcedure(struct SCRIPT * script, char *  token);

/**
 * isStaticScriptObject()
 * @param the current token
 * @return 1 if the token is the script object (WScript), otherwise -1
 * Test if the given token is the static script object
 */
int isStaticScriptObject(char * token);

/**
 * accessLine()
 * accessManagers()
 * @param the script structure
 * @param the line location (main, procedure or function)
 * @param the line index
 * @return a pointer on the line structure (resp. managers structure)
 */
#define MAINLEVEL 0x00000000
#define FUNCLEVEL 0x80000000
#define PROCLEVEL 0xF0000000
struct LINE * accessLine(struct SCRIPT * script, unsigned long location, int lineindex);
struct MANAG_ENTRY * accessManagers(struct SCRIPT * script, unsigned long location);



